﻿using System.Collections.Generic;
using XProject.DataVisit.Model;
using XProject.Commons.BaseUtil;
using log4net;
using NHibernate;
using NHibernate.Criterion;
using Spring.Data.NHibernate;
using System.Data;
using System.Collections;
using System;

namespace XProject.DataVisit.DAL
{
    /// <summary>
    /// 提供了DAL的一些基本的操作方法
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class AbstractSupportDal<T> : BaseSupportDal, IProjectDal
        where T : IProjectModel
    {
        /// <summary>
        /// 保持一个模型对象到数据库中并返回这个对象.
        /// 每次调用都会开启和关闭事务, 如果有多个对象需要保存. 请考虑使用集合的方式保存.
        /// 这样会带来更高的效率.
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual T Save(T entity)
        {
            Template.Save(entity);
            return entity;
        }

        /// <summary>
        /// 保存集合里的对象
        /// </summary>
        /// <param name="entitys"></param>
        public virtual void Save(ICollection<T> entitys)
        {
            Template.Execute(delegate(ISession session)
            {
                foreach (T a in entitys)
                {
                    session.Save(a);
                }
                return entitys.Count;
            });
        }

        /// <summary>
        /// 从数据库中删除一个传入的持久对象并返回这个对象.
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual T Delete(T entity)
        {
            Template.Delete(entity);
            return entity;
        }

        /// <summary>
        /// 从数据库中删除集合中的持久对象
        /// </summary>
        /// <param name="entitys"></param>
        public virtual void Delete(System.Collections.ICollection entitys)
        {
            Template.DeleteAll(entitys);
        }

        /// <summary>
        /// 用HQL语句删除数据库中的对象
        /// </summary>
        /// <param name="hql"></param>
        public virtual void Delete(string hql)
        {
            Template.Delete(hql);
        }
        /// <summary>
        /// 更新一个持久对象到数据库中.
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual T Update(T entity)
        {
            Template.Update(entity);
            return entity;
        }

        /// <summary>
        /// 先尝试更新传入的持久对象, 如果数据库中没有对应的记录. 就创建这条记录.
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual T UpdateOrSave(T entity)
        {
            Template.SaveOrUpdate(entity);
            return entity;
        }

        /// <summary>
        ///返回一个HQL语句执行的结果集.
        /// </summary>
        /// <param name="hql"></param>
        /// <returns></returns>
        public virtual ICollection<T> GetByQuery(string hql)
        {
            //ICollection<T> t = CollectionUtils.TypedCollection<T>(Template.FindByNamedQuery(hql));
            return CollectionUtils.TypedCollection<T>(Template.Find(hql));
            //return t;
        }

        public virtual T GetById(object id)
        {
            return (T)Template.Get(typeof(T), id);
        }
        /// <summary>
        /// 尝试传入一个对象，返回此对象模型的分页
        /// </summary>
        /// <param name="entity">类型实体</param>
        /// <param name="pagesize">每页显示数量</param>
        /// <param name="current">当前页数</param>
        /// <param name="paramnames">属性名集合，_表示需要like操作</param>
        /// <param name="param">参数</param>
        /// <param name="sortdesc">是否需要倒序</param>
        /// <param name="ordername">倒序字段</param>
        /// <returns></returns>
        public virtual IList GetCurrentPageData(T entity,int pagesize,int current,string [] paramnames,string [] param,bool sortdesc,string ordername)
        {
            if (param.Length > 0)
            {
                ICriteria param1 = Session.CreateCriteria(entity.GetType());
                if (sortdesc)
                {
                    param1.AddOrder(Order.Desc(ordername));
                }
                param1.SetMaxResults(pagesize);
                param1.SetFirstResult((current-1)*pagesize);
                for (int i = 0; i < paramnames.Length; i++)
                {
                    if (paramnames[i].IndexOf('_') >= 0)
                    {
                        if (paramnames[i].IndexOf('#') >= 0)
                        {
                            param1.Add(Expression.Like(paramnames[i].Replace('_', ' ').Replace('#', ' ').Trim(), new Guid(param[i])));
                        }
                        else
                        {
                            if (paramnames[i].IndexOf('*') >= 0)
                            {
                                param1.Add(Expression.Like(paramnames[i].Replace('_', ' ').Replace('*', ' ').Trim(), Convert.ToInt32(param[i])));
                            }
                            else
                            {
                                param1.Add(Expression.Like(paramnames[i].Replace('_', ' ').Trim(), param[i]));
                            }
                        }
                    }
                    else
                    {
                        if (paramnames[i].IndexOf('#') >= 0)
                        {
                            param1.Add(Expression.Eq(paramnames[i].Replace('#', ' ').Trim(), new Guid(param[i])));
                        }
                        else
                        {
                            if (paramnames[i].IndexOf('*') >= 0)
                            {
                                param1.Add(Expression.Eq(paramnames[i].Replace('*',' ').Trim(), Convert.ToInt32(param[i])));
                            }
                            else
                            {
                                param1.Add(Expression.Eq(paramnames[i], param[i]));
                            }
                        }
                    }
                }
                return param1.List();
            }
            else
            {
                if (sortdesc)
                {
                    return Session.CreateCriteria(entity.GetType()).SetMaxResults(pagesize).SetFirstResult((current - 1) * pagesize).AddOrder(Order.Desc(ordername)).List();
                }
                else
                {
                    return Session.CreateCriteria(entity.GetType()).SetMaxResults(pagesize).SetFirstResult((current - 1) * pagesize).List();
                }
            }
        }

        /// <summary>
        /// 尝试传入一个对象，返回此对象模型的分页总数据
        /// </summary>
        /// <param name="entity">类型实体</param>
        /// <param name="paramnames">属性名集合，_表示需要like操作</param>
        /// <param name="param">参数</param>
        /// <returns></returns>
        public virtual int GetPageDataCount(T entity,string[] paramnames, string[] param)
        {
            if (param.Length > 0)
            {
                ICriteria param1 = Session.CreateCriteria(entity.GetType());
                for (int i = 0; i < paramnames.Length; i++)
                {
                    if (paramnames[i].IndexOf('_') > 0)
                    {
                        if (paramnames[i].IndexOf('#') >= 0)
                        {
                            param1.Add(Expression.Like(paramnames[i].Replace('_', ' ').Replace('#', ' ').Trim(), new Guid(param[i])));
                        }
                        else
                        {
                            if (paramnames[i].IndexOf('*') >= 0)
                            {
                                param1.Add(Expression.Like(paramnames[i].Replace('_', ' ').Replace('*', ' ').Trim(), Convert.ToInt32(param[i])));
                            }
                            else
                            {
                                param1.Add(Expression.Like(paramnames[i].Replace('_', ' ').Trim(), param[i]));
                            }
                        }
                    }
                    else
                    {
                        if (paramnames[i].IndexOf('#') >= 0)
                        {
                            param1.Add(Expression.Eq(paramnames[i].Replace('#', ' ').Trim(), new Guid(param[i])));
                        }
                        else
                        {
                            if (paramnames[i].IndexOf('*') >= 0)
                            {
                                param1.Add(Expression.Eq(paramnames[i].Replace('*', ' ').Trim(), Convert.ToInt32(param[i])));
                            }
                            else
                            {
                                param1.Add(Expression.Eq(paramnames[i], param[i]));
                            }
                        }
                    }
                }
                return param1.List().Count;
            }
            else
            {
                return Session.CreateCriteria(entity.GetType()).List().Count;
            }
        }

        public virtual ICollection<T> GetAll()
        {
            return CollectionUtils.TypedCollection<T>(Template.LoadAll(typeof(T)));
        }
    }
}
